/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include "network.h"

Network::Network(QObject *parent) : QObject(parent)
{
    initConnect();
    //初始化dbus
    initConnectionInfo();
}
//检查网络
void Network::checkNetWork()
{
    qDebug() << " ##### Function Positioning ##### 检查网络 ##### " <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

    QNetworkConfigurationManager mgr;
    if (mgr.isOnline()) {
        qDebug() << " ##### Function Positioning ##### QNetworkConfigurationManager ##### " <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
        //判断网络是否有连接，不一定能上网，如果连接了，则开始检查互联网是否可以ping通
        QHostInfo::lookupHost("www.gov.cn", this, SLOT(checkNetAvailable(QHostInfo)));
    } else {
        ErrorReact::getInstance()->networkFeedBack(false, "无网络");
        emit effectiveNetwork(false);
    }
}
//检查网络可用
void Network::checkNetAvailable(const QHostInfo &host)
{
    qDebug() << " ##### Function Positioning ##### 检查网络可用 ##### " <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    //判断网络可用---返回错误原因
    if (host.error() != QHostInfo::NoError) {
        ErrorReact::getInstance()->networkFeedBack(false, host.errorString());
        emit effectiveNetwork(false);
    } else {
        emit effectiveNetwork(true);
    }
}
void Network::initConnectionInfo()
{
    // service名,path,interface；systemBus() or sessionBus()
    QDBusInterface interface("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager",
                             "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
    // method：get（接口名，属性名）  ----返回值为：Variant-----返回当前的所有连接的网络
    QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections");
    // outArgs放返回的数据
    QList<QVariant> outArgs = result.arguments();
    QVariant first = outArgs.at(0);
    QDBusVariant dbvFirst = first.value<QDBusVariant>();
    QVariant vFirst = dbvFirst.variant();
    QDBusArgument dbusArgs = vFirst.value<QDBusArgument>();

    QDBusObjectPath objPath;
    dbusArgs.beginArray();
    //循环存
    while (!dbusArgs.atEnd()) {
        dbusArgs >> objPath;
        m_oldPaths.append(objPath);
        //目的可能是检测更换网络：更换网络---刷新
        QDBusInterface interface("org.freedesktop.NetworkManager", objPath.path(), "org.freedesktop.DBus.Properties",
                                 QDBusConnection::systemBus());
        //获得网络类型--type是有线还是无线：802-3-ethernet，802-11-wireless
        QDBusReply<QVariant> reply = interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type");
        m_oldPathInfo.append(reply.value().toString());
    }
    dbusArgs.endArray();
}

void Network::onPropertiesChanged(QVariantMap qvm)
{
    for (QString keyStr : qvm.keys()) {
        if (keyStr == "ActiveConnections") {
            const QDBusArgument &dbusArg = qvm.value(keyStr).value<QDBusArgument>();
            QList<QDBusObjectPath> newPaths;
            dbusArg >> newPaths;
            QStringList newPathInfo;
            foreach (QDBusObjectPath objPath, newPaths) {
                QDBusInterface interface("org.freedesktop.NetworkManager", objPath.path(),
                                         "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());

                QDBusReply<QVariant> reply =
                    interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type");

                if (reply.value().toString() == "") {
                    ErrorReact::getInstance()->networkFeedBack(false, "无网络");
                    emit effectiveNetwork(false);
                }
                newPathInfo.append(reply.value().toString());
            }

            // 当前的网络连接个数由0个增为1个时，触发天气界面更新
            if (newPaths.size() == 1) {
                if (m_oldPaths.size() == 0) {
                    //等待4s，开始发送刷新信号
                    QTimer::singleShot(4 * 1000, this, SLOT(onTimeFinished()));
                }
            }

            bool isChangeOldPathInfo = true;
            for (int k = 0; k < newPathInfo.size(); k++) {
                if (newPathInfo.at(k) == "") {
                    isChangeOldPathInfo = false;
                }
            }
            if (isChangeOldPathInfo) {
                m_oldPathInfo = newPathInfo;
            }
            m_oldPaths = newPaths;
        }
    }
}

void Network::initConnect()
{
    // dbus-信号槽
    QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"),
                                         QString("/org/freedesktop/NetworkManager"),
                                         QString("org.freedesktop.NetworkManager"), QString("PropertiesChanged"), this,
                                         SLOT(onPropertiesChanged(QVariantMap)));
    QDBusConnection::sessionBus().connect(QString("org.ukui.ScreenSaver"),
                                         QString("/"),
                                         QString("org.ukui.ScreenSaver"), QString("unlock"), this,
                                         SLOT(onScreenSaverUnlock()));
}

void Network::onTimeFinished()
{
    //发送信号--刷新界面
    emit haveNet();
}

void Network::onScreenSaverUnlock()
{
    emit haveNet();
}
